﻿using System;
using System.ComponentModel.Composition;
using System.Windows.Input;
using System.Windows.Navigation;

using Action = System.Action;

namespace GaleSong
{
    /// <summary>
    ///     Base <see cref="IPart" /> class for various implementations of <see cref="IPart" />.
    /// </summary>
    public abstract class PartBase : LocalizableDisplay, IPart, IObservableParent<IPart>
    {
        private ICommand _command;
        private string _icon;
        private string _inputGestureText;
        private bool _isVisible = true;
        private ViewStrategy _viewStrategy;

        protected PartBase()
            : this(null)
        {
        }

        protected PartBase(string name)
        {
            Name = name ?? GetType().Name.Replace("Part", string.Empty);
            _execute = (() => { });
            _canExecute = (() => true);
            _command = new DelegateCommand(Execute, _canExecute);

            if (!UICommon.IsInDesignMode)
            {
                AutoUpdate = true;               
            }
        }

        protected PartBase(string name, Action execute, Func<bool> canExecute = null)
            : this(name)
        {
            _execute = execute ?? (() => { });
            _canExecute = canExecute ?? (() => true);
        }

        public IObservableCollection<IPart> Items
        {
            get { return _items; }
            set
            {
                _items = value;
                NotifyPropertyChanged(() => Items);
            }
        }

        public virtual ICommand Command
        {
            get { return _command; }
            set { _command = value; }
        }

        public string Icon
        {
            get { return _icon; }
            set
            {
                _icon = value;
                NotifyPropertyChanged(() => Icon);
            }
        }

        public string InputGestureText
        {
            get { return _inputGestureText; }
            set
            {
                _inputGestureText = value;
                NotifyPropertyChanged(() => InputGestureText);
            }
        }

        public bool IsVisible
        {
            get { return _isVisible; }
            set
            {
                _isVisible = value;
                NotifyPropertyChanged(() => IsVisible);
            }
        }

        public virtual object Content
        {
            //get { return ViewHelper.CreateView(this); }
            get { return null; }
        }

        public ViewStrategy ViewStrategy
        {
            get { return _viewStrategy; }
            set
            {
                _viewStrategy = value;
                NotifyPropertyChanged(() => ViewStrategy, () => Content);
            }
        }

        public virtual bool Cacheable
        {
            get { return true; }
        }

        [Import(typeof(IWorkbench))]
        public IWorkbench Workbench { get; set; }

        public virtual void OnAttached()
        {
        }

        #region IExecutable

        private readonly Func<bool> _canExecute;
        private readonly Action _execute;

        /// <summary>
        ///     The action associated to the ActionItem
        /// </summary>
        public virtual void Execute()
        {
            _execute();
        }

        /// <summary>
        ///     Calls the underlying canExecute function.
        /// </summary>
        public virtual bool CanExecute
        {
            get { return _canExecute(); }
        }

        #endregion

        #region Activation & Deactivation

        private IObservableCollection<IPart> _items = new BindableCollection<IPart>();

        #endregion
    }
}